package me.zhengjie.modules.system.service.impl

import me.zhengjie.common.utils.*
import me.zhengjie.common.utils.FileUtil.downloadExcel
import me.zhengjie.modules.system.domain.*
import me.zhengjie.modules.system.repository.DeptRepository
import me.zhengjie.modules.system.repository.JobRepository
import me.zhengjie.modules.system.service.JobService
import me.zhengjie.modules.system.service.dto.*
import me.zhengjie.modules.system.service.mapper.JobMapper
import jakarta.persistence.criteria.CriteriaBuilder
import jakarta.persistence.criteria.CriteriaQuery
import jakarta.persistence.criteria.Root
import jakarta.servlet.http.HttpServletResponse
import org.springframework.cache.annotation.CacheConfig
import org.springframework.cache.annotation.CacheEvict
import org.springframework.cache.annotation.Cacheable
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
import java.io.IOException

/**
 * @author Kuki Wu
 * @date 2019-03-29
 */
@Service
@CacheConfig(cacheNames = ["job"])
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = [Exception::class])
class JobServiceImpl(
    private val jobRepository: JobRepository,
    private val jobMapper: JobMapper,
    private val deptRepository: DeptRepository
) : JobService {
    @Cacheable(key = "'queryall_criteria_pageable'")
    override fun queryAll(criteria: JobQueryCriteria, pageable: Pageable?): PageResult<JobDTO?>? {
        val page =
            jobRepository.findAll({ root: Root<Job?>, criteriaQuery: CriteriaQuery<*>?, criteriaBuilder: CriteriaBuilder ->
                QueryHelp.getPredicate(
                    root,
                    criteria,
                    criteriaBuilder
                )
            }, pageable!!)
        return PageUtil.toPage(page.map { jobMapper.toDto(it) }.content, page.totalElements)
    }

    @Cacheable(key = "'queryall_criteria'")
    override fun queryAll(criteria: JobQueryCriteria): List<JobDTO> {
        val list =
            jobRepository.findAll { root: Root<Job?>, criteriaQuery: CriteriaQuery<*>?, criteriaBuilder: CriteriaBuilder ->
                QueryHelp.getPredicate(
                    root,
                    criteria,
                    criteriaBuilder
                )
            }
        return jobMapper.toDto(list) as List<JobDTO>
    }

    @Cacheable(key = "'findbyid'+#p0")
    override fun findById(id: Long): JobDTO? {
        val job = jobRepository.findById(id).orElseGet { Job() }
        ValidationUtil.isNull(job!!.id, "Job", "id", id)
        return jobMapper.toDto(job)
    }

    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = [Exception::class])
    override fun create(resources: Job): JobDTO? {
        return jobMapper.toDto(jobRepository.save(resources))
    }

    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = [Exception::class])
    override fun update(resources: Job) {
        val job = jobRepository.findById(resources.id!!).orElseGet { Job() }
        ValidationUtil.isNull(job!!.id, "Job", "id", resources.id!!)
        resources.id = job.id
        jobRepository.save(resources)
    }

    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = [Exception::class])
    override fun delete(id: Long) {
        jobRepository.deleteById(id)
    }

    @Throws(IOException::class)
    override fun download(jobDTOs: List<JobDTO>, response: HttpServletResponse?) {
        val list: MutableList<Map<String?, Any?>?> = ArrayList()
        for (jobDTO in jobDTOs) {
            val map: MutableMap<String?, Any?> = LinkedHashMap()
            map["岗位名称"] = jobDTO.name
            map["岗位状态"] = if (jobDTO.enabled!!) "启用" else "停用"
            map["创建日期"] = jobDTO.createTime
            list.add(map)
        }
        downloadExcel(list, response!!)
    }
}